package com.zhuhjay.common.handler;

import com.zhuhjay.common.domain.ResponseJson;
import com.zhuhjay.common.enums.HttpCode;
import com.zhuhjay.common.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

import static com.zhuhjay.common.domain.ResponseJson.error;

/**
 * @author ZhuHJay
 * @date 2022/3/20 16:02
 */
@ControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /** 自定义异常 **/
    @ExceptionHandler(CustomException.class)
    public ResponseJson handleCustomException(CustomException e, HttpServletRequest request) {
        String requestUri = request.getRequestURI();
        log.error("请求地址'{}',出现'{}'异常", requestUri, e.getMessage());
        return error(e.getMessage());
    }

    /** 请求媒体类型不受支持 **/
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public ResponseJson handleHttpRequestMethodNotSupported(HttpMediaTypeNotSupportedException e,
                                                            HttpServletRequest request) {
        String requestUri = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestUri, request.getHeader("Content-Type"));
        return error("请求媒体类型不支持");
    }

    /** 请求方式不支持 **/
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ResponseJson handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
                                                          HttpServletRequest request) {
        String requestUri = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestUri, e.getMethod());
        return error(e.getMessage());
    }

    /** 拦截未知的运行时异常 **/
    @ExceptionHandler(RuntimeException.class)
    public ResponseJson handleRuntimeException(RuntimeException e, HttpServletRequest request) {
        String requestUri = request.getRequestURI();
        log.error("请求地址'{}',发生未知异常.", requestUri, e);
        return error(HttpCode.SERVER_ERROR, e.getMessage());
    }

    /** 系统异常 **/
    @ExceptionHandler(Exception.class)
    public ResponseJson handleException(Exception e, HttpServletRequest request) {
        String requestUri = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestUri, e);
        return error(HttpCode.SERVER_ERROR, e.getMessage());
    }

    /** 自定义验证异常 **/
    @ExceptionHandler(BindException.class)
    public ResponseJson handleBindException(BindException e) {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return error(message);
    }

    /** 自定义验证异常 **/
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseJson handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        String message = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
        return error(message);
    }
}
